package com.hrm.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.alibaba.fastjson.JSON;
import com.hrm.domain.Dept;
import com.hrm.domain.Document;
import com.hrm.domain.DocumentExt;
import com.hrm.domain.JSONDocumentResult;
import com.hrm.domain.PageHelper;
import com.hrm.domain.User;
import com.hrm.service.DocumentService;
import com.hrm.service.UserService;
import com.hrm.service.Impl.DocumentServiceImpl;
import com.hrm.service.Impl.UserServiceImpl;

/*
 * 文件数据控制层
 */
@WebServlet(urlPatterns = { "/getDocuments", "/addDocument", "/delDocument", "/delDocuments", "/modifyDocument",
		"/downDocument" })
@SuppressWarnings("all") // 使用注解抑制警告信息
public class DocumentController extends HttpServlet {

	// 定义全局变量
	private DocumentService dms = new DocumentServiceImpl();

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String url = request.getRequestURI(); // 获取跳转路径
		// 进行截取并判断
		String operator = url.substring(url.lastIndexOf("/") + 1);
		if ("getDocuments".equals(operator)) { // 分页查询 + 模糊
			getDocuments(request, response);
		} else if ("addDocument".equals(operator)) { // 文件上传
			addDocument(request, response);
		} else if ("downDocument".equals(operator)) { // 下载指定文件
			downDocument(request, response);
		} else if ("delDocument".equals(operator)) { // 删除指定文件
			delDocument(request, response);
		} else if ("delDocuments".equals(operator)) { // 删除多个文件
			delDocuments(request, response);
		} else if ("modifyDocument".equals(operator)) { // 修改指定文件的信息
			modifyDocument(request, response);
		}
	}

	// 分页查询 + 模糊
	private void getDocuments(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PageHelper ph = new PageHelper(); // 简化分页查询
		List<DocumentExt> docus = new ArrayList<>(); // 用于存储查询到的数据
		int count = 0; // 用于记录数据条数
		HashSet<Integer> flag = new HashSet(); // 用于判断情况
		String docuName = request.getParameter("name");
		String docuTitle = request.getParameter("title");
		String docuRemark = request.getParameter("remark");
		String id = request.getParameter("userid");
		int userID = Integer.parseInt(id.replaceAll(" ", ""));
		// 获取用户信息
		UserService us = new UserServiceImpl();
		List<User> users = us.getAllUser();
		if (docuName == "" && docuTitle == "" && docuRemark == "" && userID == 0) { // 没有查询条件
			flag.add(1);
		}
		// 获取查询出的数据记录数,并设置模糊查询
		if (!flag.contains(1)) {
			docuName = "'%" + docuName + "%'";
			docuTitle = "'%" + docuTitle + "%'";
			docuRemark = "'%" + docuRemark + "%'";
		}
		if (userID != 0) {// 有用户ID
			flag.add(2);
		}
		if (flag.contains(1)) {
			count = dms.getCount(flag);
		} else {
			count = dms.getCount(flag, docuTitle, docuRemark, docuName, userID);
		}
		ph.setPageIndex(1); // 设置当前页的初始数据
		// 获取当前页
		String pageNo = request.getParameter("pageNo");
		if (pageNo != null) { // 说明点了页码
			ph.setPageIndex(Integer.parseInt(pageNo)); // 重新设置页码
			ph.setTotalPageSum(ph.getTotalPageSum()); // 重新设置总页数
		}
		ph.setPageSize(ph.getPageSize()); // 设置每页显示的记录条数
		ph.setTotalRecordSum(count); // 设置总记录条数
		// 获取当前页的数据
		if (flag.contains(1)) {
			docus = dms.getDocumentExtsByTerm(flag, ph.getStartRowNum(), ph.getPageSize());
		} else { // 有查询条件
			docus = dms.getDocumentExtsByTerm(flag, docuTitle, docuRemark, docuName, userID, ph.getStartRowNum(),
					ph.getPageSize());
		}
		ph.setTotalPageSum(ph.getTotalPageSum()); // 设置总页数
		// 将查询到的数据转化为json
		JSONDocumentResult aur = new JSONDocumentResult();
		aur.setPh(ph);
		aur.setList(docus);
		if (docus != null && docus.size() > 0) {
			aur.setMsg("success");
			aur.setUsers(users);
		}
		// 把aur对象转换成json数据
		String JobsJson = JSON.toJSONString(aur);
		// 把结果响应给客户端
		PrintWriter out = response.getWriter();
		out.write(JobsJson);
		out.flush();
		out.close();
	}

	// 文件上传
	private void addDocument(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 判断提交上来的数据是否是二进制的数据
		boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
		// 获取当前用户的ID
		User user = JSON.parseObject((String) request.getSession().getAttribute("user"), User.class);
		int userID = user.getuID();
		// 创建文件对象,用于存入数据库
		Document newDocu = new Document();
		// 创建map集合接收输入框数据
		Map<String, String> map = new HashMap();
		if (isMultiPart) {
			// 实例化一个存储数据的工厂对象
			FileItemFactory factory = new DiskFileItemFactory();
			// 实例化一个ServletFileUpload的对象并且factory作为构造参数
			ServletFileUpload sfu = new ServletFileUpload(factory);
			try {
				// 把客户端表单中的数据转换成对象集合
				List<FileItem> list = sfu.parseRequest(request);
				// 遍历这个集合
				for (FileItem item : list) {
					// 先判断item是否是普通表单文件,如果返回true就表示是普通文件
					boolean isFormFile = item.isFormField();
					int i = 0;
					if (isFormFile) {
						String field = item.getFieldName();// 表单域名
						String sr = item.getString("utf-8");
						map.put(field, sr);
					} else { // 二进制的
						// 获取文件的名字
						String uploadFileName = item.getName();
						// 文件尾缀 文件类型
						String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
						newDocu.setFileType(fileExtName);
						String fileName = uploadFileName.substring(0, uploadFileName.indexOf("."));
						newDocu.setFileName(fileName);
						String uploadPath = request.getServletContext().getRealPath("/upload");
						// 得到这个文件夹对应的File对象
						File upload_file = new File(uploadPath);
						// 判断服务器中的upload目录是否存在
						boolean isExsists = upload_file.exists(); // true:存在，false:不存在
						if (!isExsists) {
							// 如果不存在就创建该目录
							upload_file.mkdirs();
						}
						String uuid = UUID.randomUUID().toString();
						uuid = uuid.replaceAll("-", "");
						uploadFileName = uuid + "." + fileExtName;
						File file = new File(upload_file, uploadFileName);
						// 执行上传的操作
						item.write(file);
						// 将文件转为输入流
						InputStream fileIn = new FileInputStream(upload_file + "/" + uploadFileName);
						byte[] fileByte = toByteArray(fileIn);
						newDocu.setFileBytes(fileByte);
						fileIn.close(); //关闭流,不关闭则无法删除
						file.delete();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		newDocu.setFileUID(userID);
		newDocu.setFileTitle(map.get("dmtitle"));
		newDocu.setFileRemark(map.get("dmremark"));
		// 上传到数据库
		dms.addDocument(newDocu);
		String msg = "success";
		JSONDocumentResult aur = new JSONDocumentResult();
		aur.setMsg(msg);
		// 把aur对象转换成json数据
		String mJSON = JSON.toJSONString(aur);
		// 把结果响应给客户端
		PrintWriter out = response.getWriter();
		out.write(mJSON);
		out.flush();
		out.close();
	}

	// 下载指定文件
	private void downDocument(HttpServletRequest request, HttpServletResponse response) throws IOException {
		int docuID = Integer.parseInt(request.getParameter("ddid"));
		String msg = "success"; // 定义返回信息
		// 下载文件
		Document downDocument = dms.getDocumentByID(docuID);
		String fileName = downDocument.getFileName() + "." + downDocument.getFileType();
		response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		// 获取下载的输入流
		FileInputStream fis = byteToFile(downDocument.getFileBytes(), fileName);
		// 创建缓冲区
		int len = 0;
		byte[] buffer = new byte[1024];
		// 获取输出流对象
		ServletOutputStream op = response.getOutputStream();
		// 将FileOutPutStream流写入到buffer缓冲区,使用OutPutStream将缓冲区中的数据输出到客户端
		while ((len = fis.read(buffer)) > 0) {
			op.write(buffer, 0, len);
		}
		fis.close();
		op.flush();
		op.close();
	}

	// 删除指定文件
	private void delDocument(HttpServletRequest request, HttpServletResponse response) throws IOException {
		int docuID = Integer.parseInt(request.getParameter("dmid"));
		String msg = "success"; // 定义返回信息
		// 删除文件
		dms.delDocument(docuID);
		// 将返回信息封装
		JSONDocumentResult aur = new JSONDocumentResult();
		aur.setMsg(msg);
		// 把aur对象转换成json数据
		String mJSON = JSON.toJSONString(aur);
		// 把结果响应给客户端
		PrintWriter out = response.getWriter();
		out.write(mJSON);
		out.flush();
		out.close();
	}

	// 删除多个文件
	private void delDocuments(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 获取前台传过来的数据
		String documentsJSON = request.getParameter("documents");
		// 将JSON数组转换为集合
		List<String> documents = JSON.parseArray(documentsJSON, String.class);
		String msg = "success"; // 定义返回信息
		// 循环判断
		for (int i = 0; i < documents.size(); i++) {
			String documentID = documents.get(i).replaceAll(" ", "");
			// 删除文件
			dms.delDocument(Integer.parseInt(documentID));
		}
		// 将返回信息封装
		JSONDocumentResult aur = new JSONDocumentResult();
		aur.setMsg(msg);
		// 把aur对象转换成json数据
		String mJSON = JSON.toJSONString(aur);
		// 把结果响应给客户端
		PrintWriter out = response.getWriter();
		out.write(mJSON);
		out.flush();
		out.close();
	}

	// 修改指定文件的信息
	private void modifyDocument(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 获取前台传递的参数
		int docuID = Integer.parseInt(request.getParameter("id"));
		String newTitle = request.getParameter("dtitle");
		String newRemark = request.getParameter("dremark");
		String newName = request.getParameter("dname");
		String msg = ""; // 定义返回消息
		// 多种判断,防止异常
		if (newTitle != "" && newRemark != "" && newName != null) {
			// 进行修改
			Document newDocu = new Document(newTitle, newName, newRemark);
			dms.modifyDocumentByID(newDocu, docuID);
			msg = "success";
		} else {
			msg = "fail"; // 存在空数据
		}
		// 将返回信息封装
		JSONDocumentResult aur = new JSONDocumentResult();
		aur.setMsg(msg);
		// 把aur对象转换成json数据
		String mJSON = JSON.toJSONString(aur);
		// 把结果响应给客户端
		PrintWriter out = response.getWriter();
		out.write(mJSON);
		out.flush();
		out.close();
	}

	// 将输入流转为字节数组
	public byte[] toByteArray(InputStream input) throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024 * 4];
		int n = 0;
		while (-1 != (n = input.read(buffer))) {
			output.write(buffer, 0, n);
		}
		return output.toByteArray();
	}

	// 字节数组转为输入流
	public InputStream getInputStreamFromBytes(byte[] b) {
		InputStream ret = null;
		try {
			ret = new ByteArrayInputStream(b);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	// 字节数组转文件输入流
	public FileInputStream byteToFile(byte[] bytes, String fileName) {
		File file = new File(fileName);
		FileInputStream fileInputStream = null;
		try {
			OutputStream output = new FileOutputStream(file);
			BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
			bufferedOutput.write(bytes);
			fileInputStream = new FileInputStream(file);
			file.deleteOnExit();
			return fileInputStream;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return fileInputStream;
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
